package com.maxis;

import java.io.File;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.TreeMap;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

import com.classes.CaseOutlet;
import com.classes.Casemast;
import com.classes.CasemastFactory;
import com.classes.DBFactory;
import com.classes.OutletFactory;

import au.com.bytecode.opencsv.CSVReader;

public class MaxisMPOSUpdate {
	private static final String CONFIG_FILE = "/maxis.properties";
	private static final java.util.Properties appCfg = new java.util.Properties();

	private String userId = "";
	private String userGroup = "";
	private String userCountryCode = "";
	private String delimiter = "";
	private String mapUpdatePath = "";
	private String successUpdatePath = "";
	private String errorUpdatePath = "";
	
	private String transitionClose = "Close";

	public static void main(String[] args) {
		try {
			InputStream stream = MaxisMPOS.class.getResourceAsStream(CONFIG_FILE);
			if (stream != null){
				appCfg.load(stream);
			} else {
				System.out.println("MaxisMPOS Input Stream is NULL");
			}

		} catch (Exception e) {
			System.err.println("MaxisMPOS Error loading file " + CONFIG_FILE);
			System.err.println(e.getMessage());
			e.printStackTrace();
		}

		MaxisMPOSUpdate fw = new MaxisMPOSUpdate();

		fw.userId = appCfg.getProperty("user_id");
		fw.userGroup = appCfg.getProperty("user_group");
		fw.userCountryCode = appCfg.getProperty("user_country_code");
		fw.delimiter = appCfg.getProperty("file_delimiter");
		fw.mapUpdatePath = appCfg.getProperty("MapUpdatePath");
		fw.successUpdatePath = appCfg.getProperty("success_update_path");
		fw.errorUpdatePath = appCfg.getProperty("error_update_path");
		
		fw.transitionClose = appCfg.getProperty("transition_close");

		try {

			while(true){
				fw.startWork();
				//Thread.sleep(10000);
				break;
			}

		} catch(Exception e){
			e.printStackTrace();
		}
	}

	public void startWork() {
		String filePath = this.mapUpdatePath;
		System.out.println("Reading UPDATE folder " + filePath);

		File rootDir = new File( filePath );
	    File[] fileList = rootDir.listFiles();
	
	    if (fileList == null) return;

	    for ( File f : fileList ) {
	    	String fileName = f.getName().toLowerCase();
	    	
	    	if(fileName.endsWith(".txt") && fileName.startsWith("ebd")){
	    		String[] arrcsvname = f.getName().split("\\.",-1);
	    		System.out.println("ARR CSV " + arrcsvname[0]);

	    		String mainCsvStatus = this.readMainCsv(f.getAbsolutePath());
	    		this.moveAllFiles(filePath, mainCsvStatus);
	    	}

	    }
	}

	public void moveAllFiles( String filePath, String folder) {
		System.out.println("Moving files in " + filePath + " to " + folder);
		
		File rootDir = new File( filePath );
	    File[] fileList = rootDir.listFiles();
	
	    if (fileList == null) {
	    	return;
	    }
	    
	    for ( File f : fileList ) {
	    	String fileName = f.getName().toLowerCase();
	    	
	    	if(fileName.endsWith(".txt") || fileName.endsWith(".zip")){
	    		this.moveFile(f, folder);
	            this.deleteFile(f);
	    	}
	    }
	}

	public String readMainCsv(String csvpath) {
		System.out.println("Reading UPDATE status file START" + System.getProperty("line.separator"));

		String readStatus = "Failed";

		boolean ok = DBFactory.connect();
		if(ok == false){
			System.out.println(DBFactory.getMessage());
			readStatus = "Error";
		}
		else {
			if(DBFactory.startTrans()) {

				try {
					CSVReader csvFile = CSVFactory.getReader(csvpath, this.delimiter.charAt(0));
					String[] dataArray;

					boolean allDone = true;
					readStatus = "Success";

					while ((dataArray = csvFile.readNext()) != null) {
						String externalRefNo = dataArray[0];
						String referenceNo = dataArray[1];
						String maxisCode = dataArray[2];
						String merchantId = dataArray[3];
						String externalRemark = dataArray[4];
						String documentChecklist = dataArray[5];
						String updateDate = dataArray[6];

						if(maxisCode.equals("0301") && updateDate != null && updateDate.equals("") == false){
							Casemast m_case = CasemastFactory.getCaseMastByRefNo(referenceNo);
							if(m_case == null){
								System.out.println(CasemastFactory.getMessage());
								readStatus = "Error";
								allDone = false;
								break;
							}


							OutletFactory o = new OutletFactory();
							ArrayList<CaseOutlet> c_outlets = o.getCaseOutlets((int) m_case.getId());
							if(c_outlets == null){
								System.out.println(o.getMessage());
								readStatus = "Error";
								allDone = false;
								break;
							}

							CaseOutlet c_outlet = o.getCaseOutlet((int) m_case.getId(), (int) c_outlets.get(0).getOutlet().getId());
							if(c_outlet == null){
								System.out.println(o.getMessage());
								readStatus = "Error";
								allDone = false;
								break;
							}


							JSONObject obj = (JSONObject) JSONValue.parse(c_outlet.getPosForm());
							if(obj == null){
								System.out.println("Empty POS Form details.");
								readStatus = "Error";
								allDone = false;
								break;
							}

							JSONObject vendor_arr = (JSONObject) obj.get("vendor_arr");
							JSONObject vendor_details = new JSONObject();
							String vendor_name = "";

							if(vendor_arr != null){
								for(Object s : vendor_arr.keySet()){
									vendor_details = (JSONObject) vendor_arr.get(s);
									vendor_name = String.valueOf(s);
									break;
								}
							}


							JSONObject tid_facilities = new JSONObject();
							JSONObject install_data = new JSONObject();
							JSONObject facility_tids = (vendor_details.get("facility_tids") == null ? null : (JSONObject) vendor_details.get("facility_tids"));

							if(facility_tids == null) {
								System.out.println("Empty Terminal Details.");
								readStatus = "Error";
								allDone = false;
								break;
							}


							String[] arr_type = new String[] {"Wired", "Wireless", "MPOS"};

							for(Object s : facility_tids.keySet()){
								JSONObject tid_type_obj = (JSONObject) facility_tids.get(s);

								for(String t  : arr_type) {
									if(tid_type_obj.get(t) != null) {
										JSONArray tid_obj = (JSONArray) tid_type_obj.get(t);

										for(int i=0; i<tid_obj.size(); i++){
											JSONObject tid_item = (JSONObject) tid_obj.get(i);

											TreeMap<String, String> item = new TreeMap<String, String>();
											item.put("facility", s.toString());
											item.put("mid_no", tid_item.get("mid_no").toString());
											item.put("mid_no2", tid_item.get("mid_no2").toString());
											item.put("tid_no", tid_item.get("tid_no").toString());

											item.put("tid_serial", "");
											item.put("sim_serial", "");
											item.put("sam_serial", "");
											item.put("install_date", updateDate);

											tid_facilities.put(tid_item.get("tid_no").toString(), item);
										}
									}
								}
							}

							install_data.put("vendor_name", vendor_name);
							install_data.put("inst_status", "Successful");
							install_data.put("reschedule_date", "");
							install_data.put("terminal_detail", tid_facilities);
							install_data.put("last_install_date", updateDate);
							
							install_data.put("modified_date", new Date().getTime());
							install_data.put("modified_by", this.userId);

							JSONObject pos_install_arr = new JSONObject();
							
							if(c_outlet.getPosInstallation().length() > 0){
								pos_install_arr = (JSONObject) JSONValue.parse(c_outlet.getPosInstallation());
							}
							
							pos_install_arr.put(vendor_name, install_data);
							
							
							ok = o.install_note_submit((int) m_case.getId(), (int) c_outlets.get(0).getOutlet().getId(), vendor_name, "*** Successful", "Successful", "", this.userId);
							if(ok == false){
								System.out.println(o.getMessage());
								readStatus = "Error";
								allDone = false;
								break;
							}


							String terminal_install_date = "";
							String sep = "";
							
							for(Object v_name : pos_install_arr.keySet()) {
								JSONObject install_obj = (JSONObject) pos_install_arr.get(v_name);
								
								if(install_obj.get("last_install_date") != null) {
									terminal_install_date += sep + install_obj.get("vendor_name").toString() + " - " +  install_obj.get("last_install_date").toString();
									sep = ", ";
								}
							}
							
							
							ok = o.editCaseOutletInstallForm((int) m_case.getId(), (int) c_outlets.get(0).getOutlet().getId(), pos_install_arr.toString(), terminal_install_date);
							if(ok == false){
								System.out.println(o.getMessage());
								readStatus = "Error";
								allDone = false;
								break;
							}
							
							
							TreeMap<String, String> post = new TreeMap<String, String>();
							post.put("action", this.transitionClose);
							
							long hist_id = CasemastFactory.action_submit((int) m_case.getId(), post, this.userId, 2);
							if(hist_id < 0){
								System.out.println(CasemastFactory.getMessage());
								break;
							}
						}
					}

					csvFile.close();

					if(allDone){
						DBFactory.commitTrans();
					} else {
						DBFactory.rollback();
					}

				} catch (Exception e){
					e.printStackTrace();
				}
			}


			DBFactory.close();
		}



		return readStatus;
	}

	public void deleteFile(File f){
		if(f == null) {
			return;
		}
		
		f.delete();	    
	}

	
	public void moveFile(File afile, String fstatus){
    	Date dNow = new Date();
		SimpleDateFormat dformat = new SimpleDateFormat ("yyyy.MM.dd");

		String toDirectory = "";

		if(fstatus.equals("Success")){
    		File sfile = new File(this.successUpdatePath + dformat.format(dNow) + "/");
    		if (!sfile.exists()) {
    			sfile.mkdirs();
    		}

    		toDirectory = this.successUpdatePath + dformat.format(dNow) + "/";
    	}
    	else if(fstatus.equals("Error")){
    		File ffile = new File(this.errorUpdatePath + dformat.format(dNow) + "/");
    		if (!ffile.exists()) {
    			ffile.mkdirs();
    		}

    		toDirectory = this.errorUpdatePath + dformat.format(dNow) + "/";
    	}


		if(toDirectory.equals("")) {
			return;
		}
		
		
		String oldFilePath = afile.getAbsolutePath();
		String newFilePath = toDirectory + afile.getName();
 	   	
		String logstr = "";
		
		if(afile.renameTo(new File(newFilePath))){
			logstr = "SUCCESS MOVE ==> from " + oldFilePath + " to " + newFilePath + System.getProperty("line.separator");
		} else {
			logstr = "FAILED MOVE ==> from " + oldFilePath + " to " + newFilePath + System.getProperty("line.separator");
		}


		System.out.println(logstr);
    }
}
